﻿using System;
using System.Collections.Generic;
using System.Text;
using SantaSLittleIrcHelper.Irc;
using System.Threading;
using System.Drawing;

namespace SantaSLittleIrcHelper.Registration
{
    class RegistrationProcess : Process
    {

        private Thread waitingThread;

        public override void start()
        {
            this.feedbackLabel = (TLabel)Program.instance.GUI.Controls.Find("labelRegistrationFeedback", true)[0];
            if (!Program.instance.IRC.IsConnected)
            {
                this.invokeSetFeedbackMessage(Color.Orange, "connecting");
                Program.instance.connect();
                return;
            }
            this.invokeSetFeedbackMessage(Color.Orange, "processRunning");


            Settings s = Program.instance.settings;
            if (String.IsNullOrEmpty(s.nsEmail) || String.IsNullOrEmpty(s.nsUsername) || String.IsNullOrEmpty(s.nsPassword))
            {
                Program.instance.consoleWrite("Please enter a username, a password and an email address");
                this.invokeSetFeedbackMessage(Color.Red, "registrationErrorDataMissing", s.nsUsername);
                RegistrationAssistant.Instance.stateChanged(lastActionDone.NicknameNotSuccessfulRegisteredDataMissing);
                Program.instance.killProcess();
            }
            else if (s.nsPassword.Length < 5)
            {
                Program.instance.consoleWrite("Your password is too short. It needs to be at least 5 characters long.");
                this.invokeSetFeedbackMessage(Color.Red, "registrationErrorInvalidPassword", s.nsUsername);
                RegistrationAssistant.Instance.stateChanged(lastActionDone.NicknameNotSuccessfulRegisteredInvalidPassword);
                Program.instance.killProcess();
            }
            else
            {
                Program.instance.IRC.WriteLine(Rfc2812.Nick(s.nsUsername));
                Program.instance.consoleWrite("Trying to rename");
                this.step = new StepCallback(this.renamed);
                this.triggerString = s.nsUsername;
            }
        }

        public void renamed(String msg)
        {
            Settings s = Program.instance.settings;
            if (msg.Contains("Nickname is currently in use"))
            {
                Program.instance.consoleWrite("Nickname change failed, nickname is in use.");
                Program.instance.IRC.WriteLine(Rfc2812.Nick(Program.instance.nickname));
                this.step = new StepCallback(this.renamerBack);
                this.triggerString = "NICK";
                this.invokeSetFeedbackMessage(Color.Red, "registrationErrorNicknameInUse", s.nsUsername);
                RegistrationAssistant.Instance.stateChanged(lastActionDone.NicknameNotSuccessfulRegisteredNicknameInUse);
            }
            else if (msg.Contains("NICK"))
            {
                Program.instance.consoleWrite("Successfully renamed. The server requires us to wait one minute before registering the username.");
                Program.instance.consoleWrite("The process will be resumed automatically after 60 seconds. Please wait...");
                this.step = new StepCallback(this.registered);
                this.triggerString = "NickServ";
                this.waitingThread = new Thread(new ThreadStart(this.registerWait));
                waitingThread.Start();
            }
        }

        public void registerWait()
        {
            for (int i = 61; i >= 0; i--)
            {
                Thread.Sleep(1000);
                this.invokeSetFeedbackMessage(Color.Orange, "registrationWaiting", i.ToString());
            }
            this.register();
        }

        public void register()
        {
            Settings s = Program.instance.settings;
            Program.instance.consoleWrite("One minute has elapsed. Registering the nickname now!");
            Program.instance.IRC.WriteLine(Rfc2812.Privmsg("nickserv", "register " + s.nsPassword + " " + s.nsEmail));
        }

        public void registered(String msg)
        {
            Settings s = Program.instance.settings;
            if (msg.Contains("A passcode has been sent to"))
            {
                Program.instance.consoleWrite("Registration successful. The account needs to be confirmed now.");
                Program.instance.consoleWrite("The passcode has been sent to " + s.nsEmail + ". Please copy the passcode or the line with the passcode and paste it into the confirmation code field, then click \"Confirm\".");
                this.invokeSetFeedbackMessage(Color.Green, "registrationSuccessful", s.nsUsername);
                RegistrationAssistant.Instance.stateChanged(lastActionDone.NicknameSuccessfulRegistered);
                Program.instance.IRC.WriteLine(Rfc2812.Nick(Program.instance.nickname));
                this.step = new StepCallback(this.renamerBack);
                this.triggerString = "NICK";
            }
            else if (msg.Contains("has already been requested, please check your e-mail address for the pass"))
            {
                Program.instance.consoleWrite("This username has been registered, but not confirmed yet.");
                Program.instance.consoleWrite("If it has been registered by you, check your mailbox for the mail with the passcode, paste it into the confirmation code field and click \"Confirm\".");
                Program.instance.IRC.WriteLine(Rfc2812.Nick(Program.instance.nickname));
                this.step = new StepCallback(this.renamerBack);
                this.triggerString = "NICK";
                this.invokeSetFeedbackMessage(Color.Red, "registrationErrorNicknameAlreadyRequested", s.nsUsername);
                RegistrationAssistant.Instance.stateChanged(lastActionDone.NicknameNotSuccessfulRegisteredNicknameAlreadyRequested);
            }
            else if (msg.Contains("This nickname is registered and protected"))
            {
                this.waitingThread.Abort();
                Program.instance.consoleWrite("This username is already registered. Please use another one.");
                Program.instance.IRC.WriteLine(Rfc2812.Nick(Program.instance.nickname));
                this.step = new StepCallback(this.renamerBack);
                this.triggerString = "NICK";
                this.invokeSetFeedbackMessage(Color.Red, "registrationErrorNicknameAlreadyRegistered", s.nsUsername);
                RegistrationAssistant.Instance.stateChanged(lastActionDone.NicknameNotSuccessfulRegisteredNicknameAlreadyRegistered);
            }
            else if (msg.Contains("is not a valid e-mail address"))
            {
                Program.instance.consoleWrite("supplied invalid email address");
                Program.instance.IRC.WriteLine(Rfc2812.Nick(Program.instance.nickname));
                this.step = new StepCallback(this.renamerBack);
                this.triggerString = "NICK";
                this.invokeSetFeedbackMessage(Color.Red, "registrationErrorInvalidEmail", s.nsUsername);
                RegistrationAssistant.Instance.stateChanged(lastActionDone.NicknameNotSuccessfulRegisteredInvalidEmail);

            }
        }

        public void renamerBack(String msg)
        {
            if (msg.Contains(Program.instance.nickname))
            {
                Program.instance.consoleWrite("Process done.");
                Program.instance.killProcess();
            }
        }

    }
}
